package gutil

import (
	"container/list"
	"sync"
)

type Linklist struct {
	lock *sync.RWMutex
	list *list.List
}

func NewLinkList() *Linklist {
	var link Linklist
	link.Init()
	return &link
}

func (l *Linklist) Add(value interface{}) {
	l.lock.Lock()
	contain, _ := l.Contains(value)
	if !contain {
		l.list.PushFront(value)
	}
	l.lock.Unlock()
}
func (l *Linklist) Len() int {
	return l.list.Len()
}
func (l *Linklist) GetList() *list.List {
	l.lock.RLock()
	m := l.list
	l.lock.RUnlock()
	return m
}

func (l *Linklist) Delete(value interface{}) {
	l.lock.Lock()
	contain, e := l.Contains(value)
	if contain {
		l.list.Remove(e)
	}
	l.lock.Unlock()
}

func (l *Linklist) DeleteAll() {
	l.lock.Lock()
	for {

		if l.Len() == 0 {
			break
		}
		l.list.Remove(l.list.Front())

	}
	l.lock.Unlock()

}

func (l *Linklist) GetArray(start int, num int) []interface{} {
	l.lock.RLock()
	data := make([]interface{}, 0)
	var index int = 0

	for e := l.list.Front(); e != nil; e = e.Next() {
		if index >= start && index < (start+num) {
			data = append(data, e.Value)
		}
		if index >= (start + num) {
			break
		}
		index++
	}
	l.lock.RUnlock()
	return data
}
func (l *Linklist) GetAllArray() []interface{} {
	l.lock.RLock()
	data := make([]interface{}, 0)
	for e := l.list.Front(); e != nil; e = e.Next() {
		data = append(data, e.Value)

	}
	l.lock.RUnlock()
	return data
}

func (l *Linklist) Contains(value interface{}) (bool, *list.Element) {
	for e := l.list.Front(); e != nil; e = e.Next() {
		if e.Value == value {
			return true, e
		}
	}
	return false, nil
}
func (l *Linklist) Init() {
	if l.list == nil {
		l.list = list.New()
		l.lock = new(sync.RWMutex)
	}
}
